home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Library / icon.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  14KB  |  507 lines

  1. /*
  2.  * icon.c  V3.1
  3.  *
  4.  * ToolManager Objects Icon class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. static const struct TagItem TagsToFlags[] = {
  20.  TMOP_ShowName, DATA_ICONF_SHOWNAME,
  21.  TAG_DONE
  22. };
  23.  
  24. /* Icon class instance data */
  25. struct IconClassData {
  26.  ULONG                icd_Flags;
  27.  ULONG                icd_LeftEdge;
  28.  ULONG                icd_TopEdge;
  29.  void                *icd_AppObject;
  30.  struct TMMemberData *icd_ExecObject;
  31.  Object              *icd_ImageObject;
  32.  struct TMImageData  *icd_Image;
  33.  struct TMMemberData *icd_SoundObject;
  34. };
  35. #define TYPED_INST_DATA(cl, o) ((struct IconClassData *) INST_DATA((cl), (o)))
  36.  
  37. /* Create icon */
  38. #define DEBUGFUNCTION CreateIcon
  39. static BOOL CreateIcon(Object *obj, struct IconClassData *icd)
  40. {
  41.  BOOL rc = FALSE;
  42.  
  43.  /* Get image data */
  44.  if (icd->icd_Image = (struct TMImageData *)
  45.                        DoMethod(icd->icd_ImageObject, TMM_GetImage, obj,
  46.                                 NULL)) {
  47.   struct DiskObject *diskobj = icd->icd_Image->tmid_ImageData;
  48.  
  49.   ICONCLASS_LOG(LOG1(Image Data, "0x%08lx", icd->icd_Image))
  50.  
  51.   /* Set icon position */
  52.   diskobj->do_CurrentX = icd->icd_LeftEdge;
  53.   diskobj->do_CurrentY = icd->icd_TopEdge;
  54.  
  55.   /* Create icon */
  56.   if (icd->icd_AppObject =
  57.        CreateAppIcon(obj, diskobj, icd->icd_Flags & DATA_ICONF_SHOWNAME)) {
  58.  
  59.    ICONCLASS_LOG(LOG1(AppObject, "0x%08lx", icd->icd_AppObject))
  60.  
  61.    /* All OK */
  62.    rc = TRUE;
  63.   }
  64.  }
  65.  
  66.  ICONCLASS_LOG(LOG1(Result, "%ld", rc))
  67.  
  68.  return(rc);
  69. }
  70.  
  71. /* Remove icon */
  72. static void RemoveIcon(Object *obj, struct IconClassData *icd)
  73. {
  74.  /* Remove icon */
  75.  if (icd->icd_AppObject) {
  76.   DeleteAppIcon(icd->icd_AppObject, obj);
  77.   icd->icd_AppObject = NULL;
  78.  }
  79.  
  80.  /* Image object attached? Release it */
  81.  if (icd->icd_Image) {
  82.   DoMethod(icd->icd_Image->tmid_MemberData.tmmd_Object,
  83.            TMM_Detach, icd->icd_Image);
  84.   icd->icd_Image = NULL;
  85.  }
  86. }
  87.  
  88. /* Icon class method: OM_NEW */
  89. #undef  DEBUGFUNCTION
  90. #define DEBUGFUNCTION IconClassNew
  91. static ULONG IconClassNew(Class *cl, Object *obj, struct opSet *ops)
  92. {
  93.  ICONCLASS_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  94.                 PrintTagList(ops->ops_AttrList)))
  95.  
  96.  /* Call SuperClass */
  97.  if (obj = (Object *) DoSuperMethodA(cl, obj, (Msg) ops)) {
  98.   struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  99.  
  100.   /* Initialize instance data */
  101.   icd->icd_Flags       = 0;
  102.   icd->icd_AppObject   = NULL;
  103.   icd->icd_ExecObject  = NULL;
  104.   icd->icd_ImageObject = NULL;
  105.   icd->icd_Image       = NULL;
  106.   icd->icd_SoundObject = NULL;
  107.  }
  108.  
  109.  return((ULONG) obj);
  110. }
  111.  
  112. /* Icon class method: OM_DISPOSE */
  113. #undef  DEBUGFUNCTION
  114. #define DEBUGFUNCTION IconClassDispose
  115. static ULONG IconClassDispose(Class *cl, Object *obj, Msg msg)
  116. {
  117.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  118.  
  119.  ICONCLASS_LOG(LOG0(Disposing))
  120.  
  121.  /* Sound object attached? Release it */
  122.  if (icd->icd_SoundObject) DoMethod(icd->icd_SoundObject->tmmd_Object,
  123.                                     TMM_Detach, icd->icd_SoundObject);
  124.  
  125.  /* Remove icon */
  126.  RemoveIcon(obj, icd);
  127.  
  128.  /* Exec object attached? Release it */
  129.  if (icd->icd_ExecObject) DoMethod(icd->icd_ExecObject->tmmd_Object,
  130.                                    TMM_Detach, icd->icd_ExecObject);
  131.  
  132.  /* Call SuperClass */
  133.  return(DoSuperMethodA(cl, obj, msg));
  134. }
  135.  
  136. /* Icon class method: TMM_Release */
  137. #undef  DEBUGFUNCTION
  138. #define DEBUGFUNCTION IconClassRelease
  139. static ULONG IconClassRelease(Class *cl, Object *obj, struct TMP_Detach *tmpd)
  140. {
  141.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  142.  
  143.  ICONCLASS_LOG(LOG2(Arguments, "Data 0x%08lx Member 0x%08lx",
  144.                     tmpd->tmpd_MemberData, tmpd->tmpd_MemberData->tmmd_Member))
  145.  
  146.  /* Exec or Sound object deleted? */
  147.  if (icd->icd_ExecObject == tmpd->tmpd_MemberData)
  148.   icd->icd_ExecObject = NULL;
  149.  else if (icd->icd_SoundObject == tmpd->tmpd_MemberData)
  150.   icd->icd_SoundObject = NULL;
  151.  else {
  152.  
  153.   /* Remove icon first */
  154.   DeleteAppIcon(icd->icd_AppObject, obj);
  155.  
  156.   /* Reset pointers */
  157.   icd->icd_AppObject   = NULL;
  158.   icd->icd_ImageObject = NULL;
  159.   icd->icd_Image       = NULL;
  160.  }
  161.  
  162.  /* Detach object */
  163.  DoMethod(tmpd->tmpd_MemberData->tmmd_Object, TMM_Detach,
  164.           tmpd->tmpd_MemberData);
  165.  
  166.  /* Return 1 to indicate that the method is implemented */
  167.  return(1);
  168. }
  169.  
  170. /* Icon class method: TMM_ParseIFF */
  171. #undef  DEBUGFUNCTION
  172. #define DEBUGFUNCTION IconClassParseIFF
  173. static ULONG IconClassParseIFF(Class *cl, Object *obj,
  174.                                struct TMP_ParseIFF *tmppi)
  175. {
  176.  BOOL rc = FALSE;
  177.  
  178.  /* Forward method to SuperClass */
  179.  if (DoSuperMethodA(cl, obj, (Msg) tmppi)) {
  180.   struct StoredProperty *sp;
  181.  
  182.   ICONCLASS_LOG(LOG0(FORM TMIC chunk parsed OK))
  183.  
  184.   /* Check for mandatory DATA property */
  185.   if (sp = FindProp(tmppi->tmppi_IFFHandle, ID_TMIC, ID_DATA)) {
  186.    struct IconClassData *icd      = TYPED_INST_DATA(cl, obj);
  187.    struct IconDATAChunk *idc      = sp->sp_Data;
  188.    struct TMHandle      *tmh;
  189.  
  190.    ICONCLASS_LOG(LOG4(Data1,
  191.                       "Flags 0x%08lx Exec 0x%08lx Image 0x%08lx Sound 0x%08lx",
  192.                       idc->idc_Standard.sdc_Flags, idc->idc_ExecObject,
  193.                       idc->idc_ImageObject, idc->idc_SoundObject))
  194.    ICONCLASS_LOG(LOG2(Data2, "Left %ld Top %ld",
  195.                       idc->idc_LeftEdge, idc->idc_TopEdge))
  196.  
  197.    /* Initialize class data */
  198.    icd->icd_Flags    = idc->idc_Standard.sdc_Flags & DATA_ICONF_MASK;
  199.    icd->icd_LeftEdge = idc->idc_LeftEdge;
  200.    icd->icd_TopEdge  = idc->idc_TopEdge;
  201.  
  202.    /* Get TMHandle */
  203.    GetAttr(TMA_TMHandle, obj, (ULONG *) &tmh);
  204.  
  205.    /* Find Image object */
  206.    if (icd->icd_ImageObject = FindTypedIDTMObject(tmh, idc->idc_ImageObject,
  207.                                                   TMOBJTYPE_IMAGE)) {
  208.  
  209.     ICONCLASS_LOG(LOG1(Image Object, "0x%08lx", icd->icd_ImageObject))
  210.  
  211.     /* Create icon */
  212.     if (CreateIcon(obj, icd)) {
  213.  
  214.      /* Attach Exec object */
  215.      if (idc->idc_ExecObject) {
  216.       Object *execobj;
  217.  
  218.       /* Find exec object */
  219.       if (execobj = FindTypedIDTMObject(tmh, idc->idc_ExecObject,
  220.                                         TMOBJTYPE_EXEC)) {
  221.  
  222.        ICONCLASS_LOG(LOG1(Exec, "0x%08lx", execobj))
  223.  
  224.        /* Attach to exec object */
  225.        icd->icd_ExecObject = (struct TMMemberData *)
  226.         DoMethod(execobj, TMM_Attach, obj, TMV_Attach_Normal);
  227.  
  228.        ICONCLASS_LOG(LOG1(Exec Data, "0x%08lx", icd->icd_ExecObject))
  229.       }
  230.      }
  231.  
  232.      /* Attach sound object */
  233.      if (idc->idc_SoundObject) {
  234.       Object *soundobj;
  235.  
  236.       /* Find sound object */
  237.       if (soundobj = FindTypedIDTMObject(tmh, idc->idc_SoundObject,
  238.                                          TMOBJTYPE_SOUND)) {
  239.  
  240.        ICONCLASS_LOG(LOG1(Sound, "0x%08lx", soundobj))
  241.  
  242.        /* Attach to sound object */
  243.        icd->icd_SoundObject = (struct TMMemberData *)
  244.         DoMethod(soundobj, TMM_Attach, obj, TMV_Attach_Normal);
  245.  
  246.        ICONCLASS_LOG(LOG1(Sound Data, "0x%08lx", icd->icd_SoundObject))
  247.       }
  248.      }
  249.  
  250.      /* Configuration data parsed */
  251.      rc = TRUE;
  252.     }
  253.    }
  254.   }
  255.  }
  256.  
  257.  ICONCLASS_LOG(LOG1(Result, "%ld", rc))
  258.  
  259.  return(rc);
  260. }
  261.  
  262. /* Icon class method: TMM_ParseTags */
  263. #undef  DEBUGFUNCTION
  264. #define DEBUGFUNCTION IconClassParseTags
  265. static ULONG IconClassParseTags(Class *cl, Object *obj,
  266.                                 struct TMP_ParseTags *tmppt)
  267. {
  268.  struct IconClassData *icd    = TYPED_INST_DATA(cl, obj);
  269.  struct TagItem       *tstate = tmppt->tmppt_Tags;
  270.  struct TagItem       *ti;
  271.  struct TMHandle      *tmh;
  272.  BOOL                  rc     = FALSE;
  273.  
  274.  ICONCLASS_LOG((LOG1(Tags, "0x%08lx", tmppt->tmppt_Tags),
  275.                 PrintTagList(tmppt->tmppt_Tags)))
  276.  
  277.  /* Get TMHandle */
  278.  GetAttr(TMA_TMHandle, obj, (ULONG *) &tmh);
  279.  
  280.  /* Scan tag list */
  281.  while (ti = NextTagItem(&tstate))
  282.  
  283.   /* Which tag? */
  284.   switch (ti->ti_Tag) {
  285.    case TMOP_Exec: {
  286.      Object *newobj;
  287.  
  288.      /* Release old object first */
  289.      if (icd->icd_ExecObject) DoMethod(icd->icd_ExecObject->tmmd_Object,
  290.                                        TMM_Detach, icd->icd_ExecObject);
  291.  
  292.      /* Object name valid and does the object exist? */
  293.      if (ti->ti_Data &&
  294.          (newobj = FindTypedNamedTMObject(tmh, (char *) ti->ti_Data,
  295.                                           TMOBJTYPE_EXEC))) {
  296.  
  297.        ICONCLASS_LOG(LOG1(Exec, "0x%08lx", newobj))
  298.  
  299.        /* Yes, attach new object */
  300.        icd->icd_ExecObject = (struct TMMemberData *)
  301.                               DoMethod(newobj, TMM_Attach, obj,
  302.                                        TMV_Attach_Normal);
  303.  
  304.       } else
  305.  
  306.        /* No, clear pointer */
  307.        icd->icd_ExecObject = NULL;
  308.  
  309.      ICONCLASS_LOG(LOG1(Exec Attach, "0x%08lx", icd->icd_ExecObject))
  310.     }
  311.     break;
  312.  
  313.    case TMOP_Sound: {
  314.      Object *newobj;
  315.  
  316.      /* Release old object first */
  317.      if (icd->icd_SoundObject) DoMethod(icd->icd_SoundObject->tmmd_Object,
  318.                                         TMM_Detach, icd->icd_SoundObject);
  319.  
  320.      /* Object name valid and does the object exist? */
  321.      if (ti->ti_Data &&
  322.          (newobj = FindTypedNamedTMObject(tmh, (char *) ti->ti_Data,
  323.                                           TMOBJTYPE_SOUND))) {
  324.  
  325.        ICONCLASS_LOG(LOG1(Sound, "0x%08lx", newobj))
  326.  
  327.        /* Yes, attach new object */
  328.        icd->icd_SoundObject = (struct TMMemberData *)
  329.                                DoMethod(newobj, TMM_Attach, obj,
  330.                                         TMV_Attach_Normal);
  331.  
  332.       } else
  333.  
  334.        /* No, clear pointer */
  335.        icd->icd_SoundObject = NULL;
  336.  
  337.      ICONCLASS_LOG(LOG1(Sound Attach, "0x%08lx", icd->icd_SoundObject))
  338.     }
  339.     break;
  340.  
  341.    case TMOP_Image:
  342.     /* Remove old icon first */
  343.     RemoveIcon(obj, icd);
  344.  
  345.     /* Object name valid? */
  346.     if (ti->ti_Data)
  347.  
  348.      /* Yes, get new object */
  349.      icd->icd_ImageObject = FindTypedNamedTMObject(tmh, (char *) ti->ti_Data,
  350.                                                    TMOBJTYPE_IMAGE);
  351.  
  352.     else
  353.  
  354.      /* No, clear pointer */
  355.      icd->icd_ImageObject = NULL;
  356.  
  357.     break;
  358.  
  359.    case TMOP_ShowName:
  360.     /* Remove old icon first */
  361.     RemoveIcon(obj, icd);
  362.     break;
  363.  
  364.    case TMOP_LeftEdge:
  365.     /* Remove old icon first */
  366.     RemoveIcon(obj, icd);
  367.  
  368.     icd->icd_LeftEdge = ti->ti_Data;
  369.     break;
  370.  
  371.    case TMOP_TopEdge:
  372.     /* Remove old icon first */
  373.     RemoveIcon(obj, icd);
  374.  
  375.     icd->icd_TopEdge = ti->ti_Data;
  376.     break;
  377.   }
  378.  
  379.  /* Set Flags */
  380.  icd->icd_Flags = PackBoolTags(icd->icd_Flags, tmppt->tmppt_Tags, TagsToFlags);
  381.  
  382.  /* Icon not created yet and image object valid? */
  383.  if ((icd->icd_AppObject == NULL) && icd->icd_ImageObject)
  384.  
  385.   /* Yes, create icon */
  386.   rc = CreateIcon(obj, icd);
  387.  
  388.  ICONCLASS_LOG(LOG1(Result, "%ld", rc))
  389.  
  390.  return(rc);
  391. }
  392.  
  393. /* Icon class method: TMM_Activate */
  394. #undef  DEBUGFUNCTION
  395. #define DEBUGFUNCTION IconClassActivate
  396. static ULONG IconClassActivate(Class *cl, Object *obj,
  397.                                struct TMP_Activate *tmpa)
  398. {
  399.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  400.  
  401.  ICONCLASS_LOG(LOG1(Data, "0x%08lx", tmpa->tmpa_Data))
  402.  
  403.  /* Activate sound object */
  404.  if (icd->icd_SoundObject) DoMethod(icd->icd_SoundObject->tmmd_Object,
  405.                                     TMM_Activate, NULL);
  406.  
  407.  /* Activate Exec object */
  408.  if (icd->icd_ExecObject) DoMethod(icd->icd_ExecObject->tmmd_Object,
  409.                                    TMM_Activate, tmpa->tmpa_Data);
  410.  
  411.  /* Return 1 to indicate that the method is implemented */
  412.  return(1);
  413. }
  414.  
  415. /* Icon class method: TMM_Notify */
  416. #undef  DEBUGFUNCTION
  417. #define DEBUGFUNCTION IconClassNotify
  418. static ULONG IconClassNotify(Class *cl, Object *obj,
  419.                              struct TMP_Detach *tmpd)
  420. {
  421.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  422.  
  423.  ICONCLASS_LOG(LOG2(Arguments, "Data 0x%08lx Member 0x%08lx",
  424.                     tmpd->tmpd_MemberData, tmpd->tmpd_MemberData->tmmd_Member))
  425.  
  426.  /* Image has changed, remove old icon */
  427.  RemoveIcon(obj, icd);
  428.  
  429.  /* Create new icon */
  430.  CreateIcon(obj, icd);
  431.  
  432.  /* Return 1 to indicate that the method is implemented */
  433.  return(1);
  434. }
  435.  
  436. /* Icon class dispatcher */
  437. #undef  DEBUGFUNCTION
  438. #define DEBUGFUNCTION IconClassDispatcher
  439. static __geta4 ULONG IconClassDispatcher(__A0 Class *cl, __A2 Object *obj,
  440.                                          __A1 Msg msg)
  441. {
  442.  ULONG rc;
  443.  
  444.  ICONCLASS_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  445.                     cl, obj, msg))
  446.  
  447.  switch(msg->MethodID) {
  448.   /* BOOPSI methods */
  449.   case OM_NEW:
  450.    rc = IconClassNew(cl, obj, (struct opSet *) msg);
  451.    break;
  452.  
  453.   case OM_DISPOSE:
  454.    rc = IconClassDispose(cl, obj, msg);
  455.    break;
  456.  
  457.   /* TM methods */
  458.   case TMM_Release:
  459.    rc = IconClassRelease(cl, obj, (struct TMP_Detach *) msg);
  460.    break;
  461.  
  462.   case TMM_ParseIFF:
  463.    rc = IconClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  464.    break;
  465.  
  466.   case TMM_ParseTags:
  467.    rc = IconClassParseTags(cl, obj, (struct TMP_ParseTags *) msg);
  468.    break;
  469.  
  470.   case TMM_Activate:
  471.    rc = IconClassActivate(cl, obj, (struct TMP_Activate *) msg);
  472.    break;
  473.  
  474.   case TMM_Notify:
  475.    rc = IconClassNotify(cl, obj, (struct TMP_Detach *) msg);
  476.    break;
  477.  
  478.   /* Unknown method -> delegate to SuperClass */
  479.   default:
  480.    rc = DoSuperMethodA(cl, obj, msg);
  481.    break;
  482.  }
  483.  
  484.  return(rc);
  485. }
  486.  
  487. /* Create Icon class */
  488. #undef  DEBUGFUNCTION
  489. #define DEBUGFUNCTION CreateIconClass
  490. Class *CreateIconClass(Class *superclass)
  491. {
  492.  Class *cl;
  493.  
  494.  ICONCLASS_LOG(LOG1(SuperClass, "0x%08lx", superclass))
  495.  
  496.  /* Create class */
  497.  if (cl = MakeClass(NULL, NULL, superclass, sizeof(struct IconClassData), 0))
  498.  
  499.   /* Set dispatcher */
  500.   cl->cl_Dispatcher.h_Entry = (ULONG (*)()) IconClassDispatcher;
  501.  
  502.  ICONCLASS_LOG(LOG1(Class, "0x%08lx", cl))
  503.  
  504.  /* Return pointer to class */
  505.  return(cl);
  506. }
  507.